﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.ComponentModel;

namespace ThreeByte.ActiveDeck.Content
{
    public enum InteractiveState { None, Active, Inactive };

    public class LayerRenderer : INotifyPropertyChanged
    {
        private static LayerRenderer Instance = new LayerRenderer();

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private Visibility _layerVisibility = Visibility.Visible;
        public Visibility LayerVisibility {
            get {
                return _layerVisibility;
            }
            set {
                _layerVisibility = value;
                NotifyPropertyChanged("LayerVisibility");
            }

        }

        public static readonly DependencyProperty IsInteractiveProperty = DependencyProperty.RegisterAttached(
                                                                "IsInteractive",
                                                                typeof(bool),
                                                                typeof(LayerRenderer),
                                                                new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender, IsInteractiveChanged));

        public static void IsInteractiveChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
            FrameworkElement element = (FrameworkElement)obj;
            if (GetIsInteractive(element)) {
                Binding visibilityBinding = new Binding("LayerVisibility");
                visibilityBinding.Source = Instance;
                element.SetBinding(FrameworkElement.VisibilityProperty, visibilityBinding);
            } else {
                BindingOperations.ClearBinding(element, FrameworkElement.VisibilityProperty);
            }
        }

        public static void SetIsInteractive(FrameworkElement element, Boolean value) {
            element.SetValue(IsInteractiveProperty, value);
        }

        public static bool GetIsInteractive(FrameworkElement element) {
            return (bool)element.GetValue(IsInteractiveProperty);
        }

        public static void Hide() {
            Instance.LayerVisibility = Visibility.Hidden;
        }

        public static void Show() {
            Instance.LayerVisibility = Visibility.Visible;
        }


        #region InteractiveState
        private Visibility _activeVisibility = Visibility.Visible;
        public Visibility ActiveVisibility {
            get {
                return _activeVisibility;
            }
            set {
                _activeVisibility = value;
                NotifyPropertyChanged("ActiveVisibility");
            }
        }
        private Visibility _inactiveVisibility = Visibility.Visible;
        public Visibility InactiveVisibility {
            get {
                return _inactiveVisibility;
            }
            set {
                _inactiveVisibility = value;
                NotifyPropertyChanged("InactiveVisibility");
            }
        }

        public static readonly DependencyProperty InteractiveStateProperty = DependencyProperty.RegisterAttached(
                                                                "InteractiveState",
                                                                typeof(InteractiveState),
                                                                typeof(LayerRenderer),
                                                                new FrameworkPropertyMetadata(InteractiveState.None,
                                                                    FrameworkPropertyMetadataOptions.AffectsRender, InteractiveStateChanged));

        public static void InteractiveStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) {
            FrameworkElement element = (FrameworkElement)obj;
            InteractiveState state = GetInteractiveState(element);
            switch (state) {
                case InteractiveState.None: {
                        BindingOperations.ClearBinding(element, FrameworkElement.VisibilityProperty);
                        return;
                    }
                case InteractiveState.Active: {
                        Binding visibilityBinding = new Binding("ActiveVisibility");
                        visibilityBinding.Source = Instance;
                        element.SetBinding(FrameworkElement.VisibilityProperty, visibilityBinding);
                        return;
                    }
                case InteractiveState.Inactive: {
                        Binding visibilityBinding = new Binding("InactiveVisibility");
                        visibilityBinding.Source = Instance;
                        element.SetBinding(FrameworkElement.VisibilityProperty, visibilityBinding);
                        return;
                    }
            }
        }

        public static void SetInteractiveState(FrameworkElement element, InteractiveState value) {
            element.SetValue(InteractiveStateProperty, value);
        }

        public static InteractiveState GetInteractiveState(FrameworkElement element) {
            return (InteractiveState)element.GetValue(InteractiveStateProperty);
        }

        public static void SetActive() {
            Instance.ActiveVisibility = Visibility.Visible;
            Instance.InactiveVisibility = Visibility.Hidden;
        }

        public static void SetInactive() {
            Instance.ActiveVisibility = Visibility.Hidden;
            Instance.InactiveVisibility = Visibility.Visible;
        }

        #endregion



    }
}
